package com.handy.util;

import java.io.*;

/**
 * <p>
 * String,int与byte[]的相互转换
 * </p>
 * 
 * @author rocken.zeng@gmail.com(整理)
 * @version 1.0
 */
public class BytesTool {

	/**
	 * 数组扩容
	 * 
	 * @param src
	 *            byte[] 源数组数据
	 * @param size
	 *            int 扩容的增加量
	 * @return byte[] 扩容后的数组
	 */
	public static byte[] grow(byte[] src, int size) {
		byte[] tmp = new byte[src.length + size];
		System.arraycopy(src, 0, tmp, 0, src.length);
		return tmp;
	}

	/**
	 * 将长度为四的字节数组转换为int.
	 * 
	 * @param msg
	 *            byte[] 源字节数组
	 * @param start
	 *            int 从该数组的start开始四个字节
	 * @return int 转换所得的int值
	 */
	public static int getUINT4(byte[] msg, int start) {
		if (msg.length <= start + 3) {
			return 0;
		}
		int r = 0;
		r |= 0x00FF & msg[start];
		r = r << 8;
		r |= 0x00FF & msg[start + 1];
		r = r << 8;
		r |= 0x00FF & msg[start + 2];
		r = r << 8;
		r |= 0x00FF & msg[start + 3];
		return r;
	}

	/**
	 * 将指定的int转为长度为４的字节数组.
	 * 
	 * @param msg
	 *            byte[] 指定数组
	 * @param start
	 *            int 指定数组开始装载的位置
	 * @param value
	 *            int 指定待转换的int
	 */
	public static void setUINT4(byte[] msg, int start, int value) {
		if (msg.length <= start + 3) {
			return;
		}
		msg[start] = (byte) (value >> 24 & 0xFF);
		msg[start + 1] = (byte) (value >> 16 & 0xFF);
		msg[start + 2] = (byte) (value >> 8 & 0xFF);
		msg[start + 3] = (byte) (value & 0xFF);
	}

	/**
	 * long转byte[].
	 * 
	 * @param n
	 *            long
	 * @return byte[]
	 */
	public static byte[] long2byte(long n) {
		byte b[] = new byte[8];
		b[0] = (byte) (int) (n >> 56);
		b[1] = (byte) (int) (n >> 48);
		b[2] = (byte) (int) (n >> 40);
		b[3] = (byte) (int) (n >> 32);
		b[4] = (byte) (int) (n >> 24);
		b[5] = (byte) (int) (n >> 16);
		b[6] = (byte) (int) (n >> 8);
		b[7] = (byte) (int) n;
		byte[] ret = new byte[4];
		System.arraycopy(b, 4, ret, 0, 4);
		return ret;
	}

	public static int byte2int(byte b[]) {
		return b[3] & 0xff | (b[2] & 0xff) << 8 | (b[1] & 0xff) << 16
				| (b[0] & 0xff) << 24;
	}

	/**
	 * 将指定长度的字节数组转换为字符串.
	 * 
	 * @param ba
	 *            byte[] 待转换的字节数组
	 * @param start
	 *            int 数组起始位置
	 * @param len
	 *            int 待转换的长度
	 * @return String 转换后的结果
	 */
	public static String byte2str(byte[] msg, int start, int len) {
		if (msg.length < start + len) {
			return null;
		}
		int valLen = 0;
		for (valLen = 0; valLen < len; valLen++) {
			if (msg[start + valLen] == '\0') {
				break;
			}
		}
		String r = new String(msg, start, valLen);
		return r;
	}

	public static String byte2str_0(byte[] msg, int start, int len) {
		if (msg.length < start + len) {
			return null;
		}
		String r = new String(msg, start, len);
		return r;
	}

	/**
	 * 将指定长度的字节数组按指定的编码转换为字符串.
	 * 
	 * @param msg
	 *            byte[] 待转换的字节数组
	 * @param start
	 *            int 数组起始位置
	 * @param len
	 *            int 待转换的长度
	 * @param charsetName
	 *            String 指定的编码
	 * @return String 转换后的结果
	 */
	public static String byte2str(byte[] msg, int start, int len,
			String charsetName) {
		if (msg.length < start + len) {
			return null;
		}
		String r = null;

		try {
			r = new String(msg, start, len, charsetName);
		} catch (UnsupportedEncodingException ex) {
		}

		return r;
	}

	/**
	 * 将指定的字符串转换为字节数组.
	 * 
	 * @param ba
	 *            byte[] 字节容器
	 * @param s
	 *            String 待转换字符
	 * @param start
	 *            int 数组的开始位置
	 * @param len
	 *            int 字节数组长度
	 */
	public static void str2byte(byte[] ba, String s, int start, int len) {
		if (s == null) {
			return;
		}
		if (ba.length < start + len) {
			return;
		}
		byte[] bs = s.getBytes();
		System.arraycopy(bs, 0, ba, start, bs.length);
	}

	/**
	 * 将指定的字符串按指定的编码转换为字节数组.
	 * 
	 * @param ba
	 *            byte[] 字节容器
	 * @param s
	 *            String 待转换字符
	 * @param start
	 *            int 数组的开始位置
	 * @param len
	 *            int 字节数组长度
	 * @param charsetName
	 *            String 指定的编码
	 */
	public static void str2byte(byte[] ba, String s, int start, int len,
			String charsetName) {
		if (s == null) {
			return;
		}
		if (ba.length < start + len) {
			return;
		}
		byte[] bs = null;
		try {
			bs = s.getBytes(charsetName);
		} catch (UnsupportedEncodingException ex) {
		}
		System.arraycopy(bs, 0, ba, start, bs.length);
	}

	/**
	 * byte[]转long
	 * 
	 * @param b
	 *            byte[]
	 * @return long
	 */
	public static long byte2long(byte b[]) {
		return (long) b[7] & (long) 255 | ((long) b[6] & (long) 255) << 8
				| ((long) b[5] & (long) 255) << 16
				| ((long) b[4] & (long) 255) << 24
				| ((long) b[3] & (long) 255) << 32
				| ((long) b[2] & (long) 255) << 40
				| ((long) b[1] & (long) 255) << 48 | (long) b[0] << 56;
	}

	public static long byte2long(byte b[], int offset) {
		return (long) b[offset + 7] & (long) 255
				| ((long) b[offset + 6] & (long) 255) << 8
				| ((long) b[offset + 5] & (long) 255) << 16
				| ((long) b[offset + 4] & (long) 255) << 24
				| ((long) b[offset + 3] & (long) 255) << 32
				| ((long) b[offset + 2] & (long) 255) << 40
				| ((long) b[offset + 1] & (long) 255) << 48
				| (long) b[offset] << 56;
	}
}
